<script setup lang="ts">
import axios from 'axios'
import SparkMD5 from 'spark-md5'
import { ref } from 'vue'

const progress = ref(0) // 上传进度
const file = ref<File | null>(null) // 用户选择的文件
// /** 手动暂停上传 */
// const isPaused = ref(false); // 是否暂停上传
// const abortControllers: any[] = []; // 存储每个分片的 AbortController

// 选择文件
function handleFileChange(e: any) {
  file.value = e.target.files[0]
}

const worker1 = new Worker('./work1.js', { type: 'module' })
// 监听 Web Worker 的消息
worker1.onmessage = (e) => {
  const { progress, md5, done } = e.data

  if (progress) {
    console.log(`当前进度: ${(progress * 100).toFixed(2)}%`)
  }

  if (done) {
    console.log(`MD5 计算完成: ${md5}`)
    worker1.terminate() // 计算完成后关闭 Worker
  }
}
// 计算MD5
// async function calculateMD5() {
//   const chunkSize = 10 * 1024 * 1024 // 每个分片大小 10MB
//   const spark = new SparkMD5.ArrayBuffer() // 初始化 SparkMD5

//   const totalChunks = Math.ceil(file.value!.size / chunkSize)
//   let currentChunk = 0

//   const startTime = performance.now() // 开始时间

//   while (currentChunk < totalChunks) {
//     const start = currentChunk * chunkSize
//     const end = start + chunkSize
//     const chunk = file.value!.slice(start, end) // 截取分片

//     const arrayBuffer = await chunk.arrayBuffer()
//     spark.append(arrayBuffer) // 添加分片数据到 SparkMD5

//     currentChunk++

//     console.log(currentChunk)
//   }

//   const endTime = performance.now() // 结束时间
//   console.log(`MD5 计算完成，耗时 ${(endTime - startTime) / 1000} 秒`)

//   return spark.end() // 返回最终的 MD5 哈希值
// }
async function calculateMD5WithWorker(file) {
  const startTime = performance.now()

  // 向 Worker 发送文件信息
  worker1.postMessage({ file })

  worker.onmessage = (e) => {
    const { progress, md5, done } = e.data

    if (progress) {
      console.log(`当前进度: ${(progress * 100).toFixed(2)}%`)
    }

    if (done) {
      const endTime = performance.now()
      console.log(`MD5 计算完成: ${md5}`)
      console.log(`耗时 ${(endTime - startTime) / 1000} 秒`)
      worker.terminate() // 计算完成后关闭 Worker
    }
  }
}

// 上传
async function uploadFile() {
  if (!file.value)
    return

  const chunkSize = 2 * 1024 * 1024 // 分片大小 2mb
  const totalChunks = Math.ceil(file.value.size / chunkSize) // 计算总块数

  const fileHash = await calculateMD5WithWorker(file) // 计算文件的哈希值

  // 获取已上传的分片列表
  const { data } = await axios.get('http://127.0.0.1:3007/exists', {
    params: { fileHash, fileName: file.value.name },
  })

  if (data.exists) {
    alert('文件已存在')
    progress.value = 100
    return
  }

  const uploadedChunks = new Set(data.uploadedChunks)

  for (let i = 0; i < totalChunks; i++) {
    if (uploadedChunks.has(i)) {
      console.log(`Chunk ${i} already uploaded. Skipping.`)
      continue // 跳过已上传的分片
    }

    const start = i * chunkSize
    const end = start + chunkSize
    const chunk = file.value.slice(start, end) // 获取当前分片的内容

    // 创建一个新的 AbortController
    // const abortController = new AbortController();
    // abortControllers.push(abortController); // 存储控制器

    const formData = new FormData()
    formData.append('fileChunk', chunk)
    formData.append('index', i.toString())
    formData.append('fileHash', fileHash)

    // 等待当前分片上传完成
    // , {
    //   signal: abortController.signal, // 绑定 AbortController 的信号
    // }
    await axios.post('http://127.0.0.1:3007/upload', formData)

    // 如果暂停标志为 true，退出循环
    // if (isPaused.value) {
    //   console.log("Upload paused");
    //   break;
    // }

    // 上传完成后更新进度
    progress.value = Math.floor(((i + 1) / totalChunks) * 100)
  }

  // 通知后端合并分片
  await axios.post('http://127.0.0.1:3007/merge', {
    fileHash,
    fileName: file.value.name,
    totalChunks,
  })
}

function resetProgress() {
  progress.value = 0
}

// const pauseUpload = () => {
//   isPaused.value = true; // 标记为暂停
//   abortControllers.forEach((controller) => controller.abort()); // 取消所有请求
//   abortControllers.length = 0; // 清空控制器列表
// };
// const resumeUpload = () => {
//   isPaused.value = false; // 标记为继续
//   uploadFile(); // 调用上传方法继续上传
// };
</script>

<template>
  <div class="container-page">
    <h1>简单文件分片上传</h1>
    <input type="file" @change="handleFileChange">
    <button :disabled="!file" @click="uploadFile">
      开始上传
    </button>
    <!-- <button @click="pauseUpload" :disabled="!file || isPaused">暂停上传</button> -->
    <!-- <button @click="resumeUpload" :disabled="!file || !isPaused">
      继续上传
    </button> -->
    <p v-if="progress > 0">
      上传进度：{{ progress }}%
    </p>
  </div>
</template>

<style scoped></style>
